package conference;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import papers.Manuscript;

import users.Author;
import users.ProgramChair;
import users.Reviewer;
import users.User;

/**
 * 
 * @author Matt
 *
 */
public class TextParse {
	/** The filename of the expected user file. **/
	public static final String USER_FILENAME = "user.txt";
	
	private File my_file;
	private String my_userfile;
	private Scanner my_scanner;
	private static List<String[]> my_list;
	private static String my_static_file;
	
	/**
	 * 
	 * @param file, the file being parsed.
	 * @throws IOException 
	 */
	public TextParse(File file) throws IOException {
		my_file = file;
		my_scanner = new Scanner(my_file);
		my_userfile = my_scanner.next();
		my_list = new ArrayList<String[]>();
		readUserFile();
		my_static_file = my_userfile;
	}
	
	/**
	 * Reads a file that contains user data called user.txt. if this file does not exist
	 * in the specified location, one will be made at that location.
	 * 
	 * @return A List of String arrays. The Arrays contain the user, conference,
	 * and role at 0, 1, and 2 respectively.
	 * @throws IOException 
	 */
	public List<String[]> readUserFile() throws IOException{
		File userFile = new File(my_userfile +
				File.separator + USER_FILENAME);
		if (!userFile.exists()){
			userFile.createNewFile();
		}
		my_scanner = new Scanner(userFile);
		ArrayList<String[]> data = new ArrayList<String[]>();
		while(my_scanner.hasNext()){
			data.add(my_scanner.nextLine().split(", "));
		}
		my_scanner.close();
		my_list = data;
		return data;
	}
	
	/**
	 * Finds and creates all the Users for a specified Conference.
	 * 
	 * @param conf the conference users are being created for
	 * @return a list of users for the given conference
	 */
	public static List<User> getUsers(String conf) {
		List<User> userList = new ArrayList<User>();
		String author = "Author";
		String reviewer = "Reviewer";
		String confName, userName, role;
		for (String[] s: my_list)
		{
			userName = s[0];
			confName = s[1];
			role = s[2];
			User user;
			if (confName.compareToIgnoreCase(conf) == 0) 
			{
				if(role.compareToIgnoreCase(author) == 0) 
				{
					user = new Author(userName);
				}
				else if(role.compareToIgnoreCase(reviewer) == 0) 
				{
					user = new Reviewer(userName);
				}
				else
				{
					user = new ProgramChair(userName);
				}
				userList.add(user);
			}
		}
		return userList;
	}

	/**
	 * Finds all roles of a specified user in a specified conference.
	 * 
	 * @param user the user whose roles are being looked for.
	 * @param conf the conference for which the users roles are being looked at.
	 * @return a list of stings that contains the roles of the specified user in the specified conference.
	 */
	public List<String> getRoles(String user, String conf){
		String userName, role, confName;
		List<String> roles = new ArrayList<String>();
		for (String[] s: my_list)
		{
			userName = s[0];
			role = s[2];
			confName = s[1];
			if(user.compareToIgnoreCase(userName) == 0 &&
					conf.compareToIgnoreCase(confName) == 0)
			{
				if (!roles.contains(roles))
				{
				roles.add(role);
				}
			}
		}
		return roles;
	}
		
	/**
	 * Finds the Program Chair of a specified conference.
	 * 
	 * @param conf the conference that is being looked at.
	 * @return the program chair of the conference.
	 */
	public ProgramChair getChair(String conf) {
		String userName, role, confName;
		ProgramChair chair = null;
		for (String[] s: my_list)
		{
			userName = s[0];
			role = s[2];
			confName = s[1];
			if (confName.compareToIgnoreCase(conf) == 0 &&
					role.compareToIgnoreCase("Program Chair") == 0)
			{
				chair = new ProgramChair(userName);
			}
		}
		if (chair == null)
		{
			
		}
		return chair;
	}
		
	/**
	 * Gets the text of the Manuscript specified.
	 * 
	 * @param aManu the manuscript to be displayed.
	 * @return the manuscript as a string.
	 */
	public static String getText(Manuscript aManu)
	{
		 StringBuilder sb = new StringBuilder();
		    
		    try {
		        BufferedReader in = new BufferedReader(new FileReader(aManu.getPaper()));
		        String str;
		        sb.append("" + aManu.getPaperName() + "\n");
		        sb.append("by " + aManu.getAuthor().getName() + "\n");
		        while ((str = in.readLine()) != null) {
		        	sb.append(str);
		        	sb.append("\n");
		        }
		        in.close();
		    } catch (IOException e) {
		    }
		return sb.toString();
	}
	
	/**
	 * Gets the text of the Reviews of Manuscript specified.
	 * 
	 * @param aManu the manuscript whose reviews need to be grabbed
	 * @return the reviews as a string
	 */
	public static String getRevText(Manuscript aManu)
	{
		 StringBuilder sb = new StringBuilder();
		    
		 for(int i = 0; i < aManu.getReviews().size(); i++){
		    	sb.append("Review " + (i + 1) + "by " + aManu.getReviews().get(i).getUser() + "\n");
		    	try {
			        BufferedReader in = new BufferedReader(new FileReader(aManu.getReviews().get(i).getReview()));
			        String str;
			        while ((str = in.readLine()) != null) {
			        	sb.append(str);
			        	sb.append("\n");
			        }
			        in.close();
			    } catch (IOException e) {
			    }
			    sb.append("===================================\n");
		 }
	     return sb.toString();	
	}

	/**
	 * Adds a new user to the user.txt file.
	 * 
	 * @param user User to be added
	 * @param conf the conference the user is a part of
	 * @return true if successful else false.
	 */
	public boolean addToFile(User user, Conference conf)
	{
		String userName = user.getName();
		String confName = conf.getConfName();
		String[] newUser = new String[3];
		boolean isOk = true;
		newUser[0] = userName;
		newUser[1] = confName;
		newUser[2] = "Author";
		for(String[] s : my_list) {
			if (s[0].compareToIgnoreCase(userName) == 0)
			{
				isOk = false;
				break;
			}
		}
		File userFile = new File(my_userfile +
				File.separator + USER_FILENAME);
		if (isOk)
		{
			try {
				BufferedWriter output = new BufferedWriter(new FileWriter(userFile, true));
				output.newLine();
				output.write(newUser[0] + ", " + newUser[1] + ", " + newUser[2]);
				output.close();
				this.readUserFile();
			} catch (IOException e) {
			}			
		}
		return isOk;
	}
	
	/**
	 * Same as addToFile but without a check of same user name.
	 * 
	 * @param user User to be added
	 * @param conf the conference the user is a part of
	 */
	public void addToFileNoCheck(User user, Conference conf)
	{
		String userName = user.getName();
		String confName = conf.getConfName();
		String[] newUser = new String[3];
		newUser[0] = userName;
		newUser[1] = confName;
		newUser[2] = "Author";
		File userFile = new File(my_userfile +
				File.separator + USER_FILENAME);
			try {
				BufferedWriter output = new BufferedWriter(new FileWriter(userFile, true));
				output.newLine();
				output.write(newUser[0] + ", " + newUser[1] + ", " + newUser[2]);
				output.close();
				this.readUserFile();
			} catch (IOException e) {
			}			
	}

	/**
	 * updates the user list of a specified conference with new users.
	 * 
	 * @param conf Conference that users are being added to.
	 */
	public void update(Conference conf)
	{
		List<User> oldList = conf.getUsers();
		List<User> newList = TextParse.getUsers(conf.getConfName());
		
		for(int i = 0; i < newList.size(); i++)
		{
			if(!oldList.contains(newList.get(i)))
			{
				try {
					conf.addUser(newList.get(i));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
	}


	public static String getFileLoc()
	{
		return my_static_file;
	}
}
